<template>
  <div class="global-container1">
    <div class="root">
      <el-tooltip
        class="item"
        effect="dark"
        content="放大"
        placement="bottom"
        style="cursor: pointer;"
      >
        <i class="fa fa-search-plus" :style="{'margin-left': marginLeftSize}" style="font-size: 20px;"
           @click="zoomFn(1.2)"></i>
      </el-tooltip>
      <el-tooltip
        class="item"
        effect="dark"
        content="缩小"
        placement="bottom"
        style="cursor: pointer;"
      >
        <i class="fa fa-search-minus" style="font-size: 20px; margin-left: 15px;"
           @click="zoomFn(0.8)"></i>
      </el-tooltip>
      <el-tooltip
        class="item"
        effect="dark"
        content="保存为图片"
        placement="bottom"
        style="cursor: pointer;"
      >
        <i class="fa fa-floppy-o" style="font-size: 20px; margin-left: 15px;" @click="dumpImage"></i>
      </el-tooltip>
      <i class="fa fa-square" aria-hidden="true" style="color: #ecf3ff; font-size: 22px; margin-left: 20px;"
      ></i>
      <span style="margin-left: 2px;">
        未编排
      </span>
      <i class="fa fa-square" aria-hidden="true" style="color: #e6f8dd; font-size: 22px; margin-left: 20px;"
      ></i>
      <span style="margin-left: 2px;">
        已编排
      </span>
      <el-button
        type="primary" style="float:right; margin-right: 5px;" size="mini" @click="backToServiceGroup"
        v-show="openType === 'detail' "
        class="el-button-primary-style"
      >
        返回
      </el-button>

      <!-- 挂载节点 -->
      <div
        id="canvasPanel"
        ref="canvasPanel"
        @dragover.prevent
      />

      <service-group-deploy-drawer
        ref="serviceGroupDeployDrawer"
        :app-name="selectAppName"
      ></service-group-deploy-drawer>
      <div
        v-if="tooltip && !isMouseDown"
        class="g6-tooltip"
        :style="`top: ${top}px; left: ${left}px;`"
      >
        名称: {{ tooltip }}
      </div>

    </div>
  </div>
</template>

<script>
  import G6 from '@antv/g6'
  import registerFactory from './components/graph/graph'
  import ItemPanel from './ItemPanel.vue'
  import PackageListSide from '@/views/appstore/components/ServiceGroupComponents/PackageListSide.vue'
  import ServiceGroupDeployDrawer from '@/views/appstore/graph/components/ServiceGroupDeployDrawer.vue'
  import ServiceGroupDeployOneServiceDialog
    from '@/views/appstore/components/ServiceGroupDeployComponents/ServiceGroupDeployOneServiceDialog.vue'


  export default {
    props: {
      serviceGroupInfo: Object,
      detailType: ""
    },
    components: {
      ServiceGroupDeployOneServiceDialog,
      ServiceGroupDeployDrawer,
      PackageListSide,
      ItemPanel
    },
    data() {
      return {
        mode: 'drag-shadow-node',
        graph: {},
        label: '',
        labelCfg: {
          fontSize: 12,
          style: {
            fill: '#fff'
          }
        },
        openType: '',
        node: {
          fill: '',
          lineDash: 'none',
          borderColor: '',
          width: 160,
          height: 60,
          shape: 'rect-node'
        },
        selectAppName: '',
        configVisible: false,
        isMouseDown: false,
        config: '',
        tooltip: '',
        top: 0,
        left: 0,
        gvStoreGroupVo: {
          appIdList: [],
          groupDescription: '',
          groupName: '',
          relationGraph: ''
        },
        type: '',
        serviceGroupInstance: {},
        nodeInfo: {
          deployId: '',
          appName: '',
          appVersion: '',
          depends: [],
          useAppliedDeploy: false,
          yamlDeploy: {}
        },
        marginLeftSize: "10px",
      }
    },
    created() {
      this.serviceGroupInstance = this.$route.params.serviceGroupInfo;
      this.openType = this.$route.params.detailType;

      if (this.serviceGroupInstance) {
        this.fetchRelationGraph();
      } else {
        this.$router.push({name: 'ServiceGroupList'});
      }
    },
    methods: {
      fetchRelationGraph() {
        this.$appManageApi.getrelationGraph(this.serviceGroupInstance.id).then((res) => {
          if (res && res.code === 200) {
            // this.serviceGroupInstance.relationGraph = res.data;
            let parse = JSON.parse(res.data);
            parse.nodes.forEach(node => {
              node.x = node.x - 300;
            })
            this.serviceGroupInstance.relationGraph = JSON.stringify(parse);
            this.$nextTick(() => {
              this.createGraphic(this.serviceGroupInstance.relationGraph);
              this.initGraphEvent();
            });
          }
        }).catch((error) => {
          console.error('Error fetching relation graph:', error);
        });
      },
      createGraphic(data) {
        const grid = new G6.Grid()
        const menu = new G6.Menu({
          offsetX: -20,
          offsetY: -50,
          itemTypes: ['node', 'edge'],
        })
        const minimap = new G6.Minimap({
          size: [250, 150]
        })
        let plugins = []
        if (this.openType === 'create' || this.openType === 'edit') {
          plugins = [menu, minimap, grid]
        } else {
          plugins = [minimap, grid]
        }
        const cfg = registerFactory(G6, {
          width: window.innerWidth,
          height: window.innerHeight,
          layout: {
            type: '' // 位置将固定
          },
          // 所有节点默认配置
          defaultNode: {
            type: 'rect-node',
            style: {
              radius: 10,
              width: 200,
              height: 50,
              cursor: 'move',
              fill: '#ecf3ff'
            },
            labelCfg: {
              fontSize: 20,
              style: {
                cursor: 'move',
                fontSize: 20
              }
            }
          },
          // 所有边的默认配置
          defaultEdge: {
            type: 'polyline-edge', // 扩展了内置边, 有边的事件
            style: {
              radius: 5,
              offset: 15,
              stroke: '#aab7c3',
              lineAppendWidth: 10, // 防止线太细没法点中
              endArrow: true
            }
          },
          // 覆盖全局样式
          nodeStateStyles: {
            'nodeState:default': {
              opacity: 1
            },
            'nodeState:hover': {
              opacity: 0.8
            },
            'nodeState:selected': {
              opacity: 0.9
            }
          },
          // 默认边不同状态下的样式集合
          edgeStateStyles: {
            'edgeState:default': {
              stroke: '#aab7c3'
            },
            'edgeState:selected': {
              stroke: '#1890FF'
            },
            'edgeState:hover': {
              animate: true,
              animationType: 'dash',
              stroke: '#1890FF'
            }
          },
          modes: {
            // 支持的 behavior
            default: ['drag-canvas', 'drag-shadow-node', 'canvas-event', 'delete-item', 'select-node', 'hover-node', 'active-edge', 'zoom-canvas'],
            originDrag: ['drag-canvas', 'drag-node', 'canvas-event', 'delete-item', 'select-node', 'hover-node', 'active-edge', 'zoom-canvas']
          },
          plugins: plugins
        })

        this.graph = new G6.Graph(cfg)
        this.restoreGraph(data)
        window.$welabxG6 = this.graph
      },
      // 初始化图事件
      initGraphEvent() {
        this.graph.on('on-node-mouseenter', e => {
          if (e && e.item) {
            this.tooltip = e.item.get('model').data.appZhname + "\n 标识：" + e.item.get('model').data.appName
            this.left = e.clientX + 40
            this.top = e.clientY - 20
            e.item.getOutEdges().forEach(edge => {
              edge.clearStates('edgeState')
              edge.setState('edgeState', 'hover')
            })
          }
        })

        // 鼠标拖拽到画布外时特殊处理
        this.graph.on('mousedown', e => {
          this.isMouseDown = true
        })
        this.graph.on('mouseup', e => {
          this.isMouseDown = false
        })
        this.graph.on('canvas:mouseleave', e => {
          this.graph.getNodes().forEach(x => {
            const group = x.getContainer()

            group.clearAnchor()
            x.clearStates('anchorActived')
          })
        })

        this.graph.on('on-node-mousemove', e => {
          if (e && e.item) {
            this.tooltip = e.item.get('model').data.appZhname + "\n 标识：" + e.item.get('model').data.appName
            this.left = e.clientX + 40
            this.top = e.clientY - 20
          }
        })

        this.graph.on('on-node-mouseleave', e => {
          if (e && e.item) {
            this.tooltip = ''
            if (e && e.item) {
              e.item.getOutEdges().forEach(edge => {
                edge.clearStates('edgeState')
              })
            }
          }
        })

        this.graph.on('before-node-removed', ({target, callback}) => {
          setTimeout(() => {
            // 确认提示
            callback(true)
          }, 1000)
        })

        this.graph.on('after-node-dblclick', e => {
          if (e && e.item) {
            console.log(e.item)
          }
        })

        this.graph.on('after-edge-selected', e => {
          this.configVisible = false
          if (e && e.item) {
            this.config = e.item.get('model').id

            this.graph.updateItem(e.item, {
              style: {
                radius: 10,
                lineWidth: 2
              }
            })
          }
        })

        this.graph.on('on-edge-mousemove', e => {
          if (e && e.item) {
            this.left = e.clientX + 40
            this.top = e.clientY - 20
          }
        })

        this.graph.on('on-edge-mouseleave', e => {
          if (e && e.item) {
            this.tooltip = ''
          }
        })

        this.graph.on('before-edge-add', ({source, target, sourceAnchor, targetAnchor}) => {
          // console.log(1414);
          setTimeout(() => {
            this.graph.addItem('edge', {
              id: `${+new Date() + (Math.random() * 10000).toFixed(0)}`, // edge id
              source: source.get('id'),
              target: target.get('id'),
              sourceAnchor,
              targetAnchor
            })
            this.refreshGraph()
          }, 100)
        })
      },
      changeMode() {
        if (this.mode === 'drag-node') {
          this.mode = 'drag-shadow-node'
          this.graph.setMode('default')
        } else {
          this.mode = 'drag-node'
          this.graph.setMode('originDrag')
        }
      },
      deleteNode(item, type) {
        this.graph.removeItem(item)
        this.configVisible = false
        this.refreshGraph()
        this.$refs.itemPanelList.filterPackageList()
      },
      refreshGraph() {
        let save = this.graph.save()
        this.graph.read(save)
      },
      // 添加节点
      addNode(transferData, {x, y}) {
        const {label, shape, fill, data, dataType} = JSON.parse(transferData)

        const model = {
          label,
          id: `${+new Date() + (Math.random() * 10000).toFixed(0)}`, // edge id
          // 形状
          type: shape,
          style: {
            fill: fill || '#ecf3ff'
          },
          // 坐标
          x,
          y,
          data,
          dataType
        }
        this.graph.addItem('node', model)
        this.refreshGraph()
        this.$refs.itemPanelList.filterPackageList()
      },
      restoreGraph(data) {
        if (data !== null) {
          let databaseModel = JSON.parse(data)
          let tmpData = {
            nodes: [],
            edges: []
          }
          databaseModel.nodes.forEach(ele => {
            let tmpNode = {}
            tmpNode.id = ele.id
            tmpNode.x = ele.x
            tmpNode.y = ele.y
            tmpNode.data = ele.data
            let tmpLabelStr = ""
            if (ele.data.appZhname.length > 13) {
              tmpLabelStr = "名称：" + ele.data.appZhname.substring(0, 12) + "...\n 标识："
            } else {
              tmpLabelStr = "名称：" + ele.data.appZhname + "\n 标识："
            }
            if (ele.data.appName.length > 13) {
              tmpLabelStr = tmpLabelStr + ele.data.appName.substring(0, 12) + "..."
            } else {
              tmpLabelStr = tmpLabelStr + ele.data.appName
            }
            // tmpNode.label = "名称：" + ele.data.appZhname + "\n 标识：" + ele.data.appName
            tmpNode.label = tmpLabelStr
            // tmpNode.label = "名称：" + ele.data.appZhname + "\n 标识：" + ele.data.appName
            tmpNode.dataType = ele.dataType
            tmpNode.style = {
              'nodeState:default': {
                'opacity': 1
              },
              'nodeState:hover': {
                'opacity': 0.8
              },
              'nodeState:selected': {
                'opacity': 0.9
              },
              'radius': 10,
              'width': 200,
              'height': 50,
              'cursor': 'move',
              'fill': '#e6f8dd'
            }
            tmpNode.labelCfg = {
              'fontSize': 20,
              'style': {
                'cursor': 'move',
                'fontSize': 15
              }
            }
            tmpNode.type = 'rect-node'
            tmpData.nodes.push(tmpNode)
          })
          databaseModel.edges.forEach(ele => {
            let tmpEdge = {}
            tmpEdge.id = ele.id
            tmpEdge.source = ele.source
            tmpEdge.target = ele.target
            tmpEdge.sourceAnchor = ele.sourceAnchor
            tmpEdge.startPoint = ele.startPoint
            tmpEdge.endPoint = ele.endPoint
            tmpEdge.type = 'polyline-edge'
            tmpEdge.style = {
              'edgeState:default': {
                'stroke': '#aab7c3',
                'lineWidth': 1
              },
              'edgeState:selected': {
                'stroke': '#1890FF'
              },
              'edgeState:hover': {
                'animate': true,
                'animationType': 'dash',
                'stroke': '#1890FF'
              },
              'radius': 5,
              'offset': 15,
              'stroke': '#aab7c3',
              'lineAppendWidth': 10,
              'endArrow': true
            }
            tmpData.edges.push(tmpEdge)
          })
          this.graph.read(tmpData)
        }
      },
      backToServiceGroup() {
        // this.$emit('update:detailType', '');
        this.$router.push({
          name: 'ServiceGroupList'
        })
      },
      zoomFn(num) {
        this.graph.zoom(num);
      },
      dumpImage() {
        this.graph.downloadFullImage(this.gvStoreGroupVo.groupName, 'image/png', {
          backgroundColor: '#ddd',
          padding: [30, 15, 15, 15],
        });
      },
    },
    // beforeMount() {
    //     this.serviceGroupInstance = this.$route.params.serviceGroupInfo
    //     if (this.serviceGroupInstance.id) {
    //       this.$appManageApi.getrelationGraph(this.serviceGroupInstance.id).then((res) => {
    //         if (res && res.code === 200) {
    //           this.serviceGroupInstance.relationGraph = res.data;
    //           this.$nextTick(() => {
    //             this.createGraphic(this.serviceGroupInstance.relationGraph);
    //             this.initGraphEvent();
    //           });
    //         }
    //       }).catch((error) => {
    //         // Handle error, if needed
    //         console.error('Error fetching relation graph:', error);
    //       });
    //     } else {
    //       console.log("!!!!!!!");

    //       // Redirect to the service group list page
    //       this.$router.push({ name: 'ServiceGroupList' });
    //     }
    //   // }
    // }
  }
</script>

<style lang="scss">
  /* 提示框的样式 */
  .g6-tooltip {
    position: fixed;
    top: 0;
    left: 0;
    font-size: 12px;
    color: #545454;
    border-radius: 4px;
    border: 1px solid #e2e2e2;
    background-color: rgba(255, 255, 255, 0.9);
    box-shadow: rgb(174, 174, 174) 0 0 10px;
    padding: 10px 8px;
  }

  .g6-minimap {
    position: absolute;
    right: 0;
    bottom: 0;
    background: #fff;
  }

  /* 新增各二级菜单全局样式布局 */
  .global-container1 {
    /* background-image: url(../../assets/back_images/background.png);  */
    background-size: cover;
    /* width: 98%; */
    /* margin-left: 1%; */
    padding: 20px;
    height: 92vh;
    display: flex;
    flex-direction: column;
    margin-bottom: 10px;
  }
</style>
